#ifndef PHYSICS_H
#define PHYSICS_H

class b2World;
class b2Body;
class b2Fixture;
class b2Shape;

class GraphicsObject;

class Physics
{
public:
    enum BodyType
    {
        BT_Static,
        BT_Kinematic,
        BT_Dynamic
    };

    struct BasicBodyParameters
    {
        bool bValid;
        QPointF pos;
        float angleRad;
    };

    struct PhysicsObject
    {
        b2Body* pBody;
        QPointer<GraphicsObject> gobject;
    };

    Physics(float worldScale, QPointF gravity = QPointF(0, 9.81f));
    ~Physics();

    // TODO: separated class for body, GraphicsObject is only 'pattern'
    bool createBody(QPointer<GraphicsObject> gobject);
    BasicBodyParameters basicBodyParameters(QPointer<GraphicsObject> gobject);

    void updateWorld(float speed = 1.0f);
    void setResolution(QPoint res);

    float toGraphicsCoordinates(float value);
    float toPhysicsCoordinates(float value);
private:
    // body methods
    b2Body* createBody(BodyType type, float initialX, float initialY, float initialAngleDeg,
                       bool bFixedRotation = false, float gravityScale = 1.0f);
    b2Fixture* createFixture(b2Body* pBody, const b2Shape* pShape, float friction, float restitution,
                             float density = 1.0f);
    b2World* m_pWorld;

    QPoint m_resolution;
    float m_fWorldScale;

    QMap<QPointer<GraphicsObject>, b2Body*> m_mapGOBody;
};

#endif // PHYSICS_H
